package com.swa99ylum.pxf.util;

import java.util.Arrays;
import java.util.List;

import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class MergedRegionUtils {
	
//	public static void get
	
	
	
	/**
	 * 获取 上方的 单元格
	 * @return
	 */
	public static XSSFCell getUpperCell(XSSFCell cell) {
		//当前 cell 的 坐标
		int columnIndex	= cell.getColumnIndex();
		int rowIndex 	= cell.getRowIndex();
		
		XSSFSheet sheet = cell.getSheet(); //本页
		
		/* rowIndex 可以 < 0，poi 不会报错*/
		XSSFRow rowUpper = sheet.getRow(rowIndex-1); //上方的 行
		
		if(rowUpper != null) {
			
			XSSFCell cellUpper = rowUpper.getCell(columnIndex); //上方的 单元格
			
			
			return cellUpper;
		}else {
			return null;
			
		}
		
	}
	
	public static XSSFCell getLowerCell(XSSFCell cell) {
		//TODO: getLowerCell(XSSFCell cell)
		return null;
	}
	
	
	
	/**
	 * 获取 左方的 单元格
	 * @return
	 */
	public static XSSFCell getLeftCell(XSSFCell cell) {
		//当前 cell 的 坐标
		int columnIndex	= cell.getColumnIndex();
		
		XSSFRow row = cell.getRow(); //本行
		
		/*
		 * poi 要求 Cell index must be >= 0
		 * Exception in thread "main" java.lang.IllegalArgumentException: Cell index must be >= 0
		 */
		if((columnIndex-1)<0) return null; 
		
		XSSFCell cellLeft = row.getCell(columnIndex-1); //左方的 单元格
		
		return cellLeft;
	}
	
	public static XSSFCell getRightCell(XSSFCell cell) {
		//TODO: getRightCell(XSSFCell cell)
		return null;
	}
	
	/**
	 * 横向 合并单元格
	 * "cell1 所在的 合并单元格"将 吸收 "cell2 所在的 合并单元格"
	 */
	public static void horizontalMerge(XSSFCell cell1, XSSFCell cell2) {
		/* step1、要求 2 个 sheet 在同一个 sheet 中  */
		if( ! inSameSheet(cell1, cell2) ) return;
		
		
		/* step2、要求 2 个 mr 的 firstRow、lastRow 一样，才能 横向合并  */
		CellRangeAddress mergedRegion1 = getMergedRegion(cell1);//获取 cell1 所在的 mr
		int[] position1 = mergedRegion1 == null ? getPosition(cell1) : getPosition(mergedRegion1);//"cell" 或 "cell 所在的 mr" 的 位置
		
		CellRangeAddress mergedRegion2 = getMergedRegion(cell2);//获取 cell2 所在的 mr
		int[] position2 = mergedRegion2 == null ? getPosition(cell2) : getPosition(mergedRegion2);//"cell" 或 "cell 所在的 mr" 的 位置
		
		if((position1[0]!=position2[0]) || (position1[1]!=position2[1])) {
			return; //不满足 合并条件，无法合并
		}
		
		
		/* step3、可以进行 "mr合并"
		 * 注意：是 使用 "cell1 所在的 mr" 吸收 "cell2 所在的 mr"
		 */

		//如果 cell 并没有处于 mr 中，则将 cell 包裹成一个 1*1 的 mr
		if(mergedRegion1 == null) mergedRegion1 = new CellRangeAddress(position1[0], position1[1], position1[2], position1[3]);
		if(mergedRegion2 == null) mergedRegion2 = new CellRangeAddress(position2[0], position2[1], position2[2], position2[3]);
		
		
		if(position1[2] < position2[2]) { //如果 mr1(cell1 所在的 mr) 在 mr2(cell2 所在的 mr) 的 左方，则 扩展 mr1 的 右沿
			mergedRegion1.setLastColumn(position2[3]);
		}else {//反之，则 扩展 mr1 的 左沿
			mergedRegion1.setFirstColumn(position2[2]);
		}
		
		getPosition(mergedRegion1);
		
		
		/*
		 * step4、在当前 sheet 中 
		 * 1、删除 "cell1 所在的 mr"、"cell2 所在的 mr"
		 * 2、新增 mr1’，即 扩展后的 mr1 
		 */
		//通过 sheet.removeMergedRegion(index) 删除 mr1、mr2
		XSSFSheet sheet = cell1.getSheet();
		int size = sheet.getNumMergedRegions();
		int index1 = getMergedRegionIndex(cell1); if(-1<index1 && index1<size) sheet.removeMergedRegion(index1);
		int index2 = getMergedRegionIndex(cell2); if(-1<index2 && index2<size) sheet.removeMergedRegion(index2);
		
		
		//TODO: 如何 居中？
//		mergedRegion1.
		sheet.addMergedRegion(mergedRegion1);
		
		
	}
	
	
	public static boolean inSameSheet(XSSFCell cell1, XSSFCell cell2) {
		XSSFWorkbook wb = cell1.getSheet().getWorkbook();
		
		XSSFSheet sheet1 = cell1.getSheet();
		XSSFSheet sheet2 = cell2.getSheet();
		
		if(wb.getSheetIndex(sheet1) == wb.getSheetIndex(sheet2)) return true;
		else return false;
	}
	
	/**
	 * 纵向 合并单元格
	 * "cell1 所在的 合并单元格"将 吸收 "cell2 所在的 合并单元格"
	 */
	public static void verticalMerge(XSSFCell cell1, XSSFCell cell2) {
		
		/* step1、要求 2 个 sheet 在同一个 sheet 中  */
		if( ! inSameSheet(cell1, cell2) ) return;
		
		
		/* step2、要求 2 个 mr 的 firstColumn、lastColumn 一样，才能 纵向合并  */
		CellRangeAddress mergedRegion1 = getMergedRegion(cell1);//获取 cell1 所在的 mr
		int[] position1 = mergedRegion1 == null ? getPosition(cell1) : getPosition(mergedRegion1);//"cell" 或 "cell 所在的 mr" 的 位置
		
		CellRangeAddress mergedRegion2 = getMergedRegion(cell2);//获取 cell2 所在的 mr
		int[] position2 = mergedRegion2 == null ? getPosition(cell2) : getPosition(mergedRegion2);//"cell" 或 "cell 所在的 mr" 的 位置
		
		if((position1[2]!=position2[2]) || (position1[3]!=position2[3])) {
			return; //不满足 合并条件，无法合并
		}
		
		/* step3、可以进行 "mr合并"
		 * 注意：是 使用 "cell1 所在的 mr" 吸收 "cell2 所在的 mr"
		 */

		//如果 cell 并没有处于 mr 中，则将 cell 包裹成一个 1*1 的 mr
		if(mergedRegion1 == null) mergedRegion1 = new CellRangeAddress(position1[0], position1[1], position1[2], position1[3]);
		if(mergedRegion2 == null) mergedRegion2 = new CellRangeAddress(position2[0], position2[1], position2[2], position2[3]);
		
		
		if(position1[0] < position2[0]) { //如果 mr1(cell1 所在的 mr) 在 mr2(cell2 所在的 mr) 的 上方，则 扩展 mr1 的 下沿
			mergedRegion1.setLastRow(position2[1]);
		}else {//反之，则 扩展 mr1 的 上沿
			mergedRegion1.setFirstRow(position2[0]);
		}
		
		getPosition(mergedRegion1);
		
		
		/*
		 * step4、在当前 sheet 中 
		 * 1、删除 "cell1 所在的 mr"、"cell2 所在的 mr"
		 * 2、新增 mr1’，即 扩展后的 mr1 
		 */
		//通过 sheet.removeMergedRegion(index) 删除 mr1、mr2
		XSSFSheet sheet = cell1.getSheet();
		int size = sheet.getNumMergedRegions();
		int index1 = getMergedRegionIndex(cell1); if(-1<index1 && index1<size) sheet.removeMergedRegion(index1);
		int index2 = getMergedRegionIndex(cell2); if(-1<index2 && index2<size) sheet.removeMergedRegion(index2);
		
		
		//TODO: 如何 居中？
//		mergedRegion1.
		sheet.addMergedRegion(mergedRegion1);
		
	}
	
	/**
	 * 获取 cell 的 位置：[上, 下, 左, 右 ] 
	 */
	public static int[] getPosition(XSSFCell cell) {
		int[] position = new int[]{cell.getRowIndex(), cell.getRowIndex(), cell.getColumnIndex(), cell.getColumnIndex()};
		
//		System.out.println("position: " + Arrays.toString(position));
		
		return position;
	}
	
	/**
	 * 获取 mr 的 位置：[上, 下, 左, 右 ] 
	 */
	public static int[] getPosition(CellRangeAddress mr) {
		int[] position = new int[]{mr.getFirstRow(), mr.getLastRow(), mr.getFirstColumn(), mr.getLastColumn()};
		
//		System.out.println("position: " + Arrays.toString(position));
		
		return position;
	}
	
	
	/**
	 * 判断：任意 2 个 cell 所在的 "合并单元格" 的 "左上角cell" 的值 是否相同
	 */
	public static boolean equals(XSSFCell cell1, XSSFCell cell2,  List<Object> exclusionList) {
		
		XSSFCell cellTL1 = getTopLeftCell(cell1);
		XSSFCell cellTL2 = getTopLeftCell(cell2);
		
		return CellUtils.equals(cellTL1, cellTL2, exclusionList);
		
	}
	/**
	 * 判断：任意 2 个 cell 所在的 "合并单元格" 的 "左上角cell" 的值 是否相同
	 */
	public static boolean equals(XSSFCell cell1, XSSFCell cell2) {
		
		XSSFCell cellTL1 = getTopLeftCell(cell1);
		XSSFCell cellTL2 = getTopLeftCell(cell2);
		
		return CellUtils.equals(cellTL1, cellTL2);
		
	}
	
	
	public static boolean equals1(XSSFCell cell1, XSSFCell cell2) {
		
		DataFormatter df = new DataFormatter();
		
		XSSFCell cellTL1 = getTopLeftCell(cell1);
		XSSFCell cellTL2 = getTopLeftCell(cell2);
		
//		String asd = cellTL1.getRawValue();
//		//System.out.println("asd => " + asd);
//		
//		String qwe = cellTL2.getRawValue();
//		//System.out.println("qwe => " + qwe);
		
//		Object s1 = cellTL1.getStringCellValue();
//		Object s2 = cellTL2.getStringCellValue();
		
		 XSSFWorkbook wb = cellTL1.getRow().getSheet().getWorkbook();
		 XSSFCellStyle cellStyle = wb.createCellStyle();
		 
		    int old_DF = cellStyle.getDataFormat();
		    
		    cellStyle.setDataFormat(0x31);
		    cellTL1.setCellStyle(cellStyle);//必须要 将 流 write 之后，再去读，才能奏效
		    cellTL2.setCellStyle(cellStyle);
		    
		    
//		    //System.out.println("QQQ => " + cellTL1.getCellTypeEnum());
		    String a1 = cellTL1.getStringCellValue();
		    String a2 = cellTL2.getStringCellValue();
//		    
//		    //System.out.println(a1);
//		    //System.out.println(a2);
		   
		    
		    /**
		     * 最终的 解决方案：
		     * 使用 getCellTypeEnum + switch-case 一起判断
		     */
		
		/**
		 * 通过 setDataFormat，统一转成 String ，在进行比较
		 */
		
		//System.out.println("cellTL1 => " +  a1);
		//System.out.println("cellTL2 => " +  a2);
		
		
		
		if(a1.equals(a2.toString())) {
			//System.out.println("相等拉   ");
		} else {
			//System.out.println("不相等   ");
		}
		
		
		return false;
	}
	

	/**
	 * 通过 cell 获取 cell 所在的 "合并单元格" 的 "左上角的 cell"
	 */
	public static XSSFCell getTopLeftCell(XSSFCell cell) {
		
		XSSFSheet sheet = cell.getSheet();
		CellRangeAddress mergedRegion = getMergedRegion(cell);
//		mergedRegion.
		
//		RegionUtil.
		
		if(mergedRegion != null) {//cell 处于 任何一个 "合并单元格" 内，则 返回 "左上角的 cell"
			
			int topIndex 	= mergedRegion.getFirstRow();
			int leftIndex 	= mergedRegion.getFirstColumn();
			
			return sheet.getRow(topIndex).getCell(leftIndex);
			
		}else {//cell 不处于 任何一个 "合并单元格" 内，则 返回 "cell 自己"
			return cell;
		}
	}
	
	public static int getMergedRegionIndex(XSSFCell cell) {
		
		CellRangeAddress mergedRegion = null;
		
		XSSFSheet sheet = cell.getSheet();
		//System.out.println("当前 sheet 的 合并单元格 的 个数：" + sheet.getNumMergedRegions());
		
		int rowIndex = cell.getRowIndex();
		int columnIndex = cell.getColumnIndex();
		
		for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
			mergedRegion = sheet.getMergedRegion(i); //mergedRegion 即为 一个 "合并单元格"
	        
			//System.out.println("4444> ("+mergedRegion.getFirstColumn()+","+mergedRegion.getFirstRow()+")-("
//					+mergedRegion.getLastColumn()+","+mergedRegion.getLastRow()+")");
			
			/**
			 * 新方法
			 */
			//如果 cell 在 mergedRegion 中
			if(mergedRegion.containsColumn(columnIndex) && mergedRegion.containsRow(rowIndex)) {
				return i;
			}
			
			/**
			 * 老方法
			int firstRow 	= mergedRegion.getFirstRow();  
			int lastRow 	= mergedRegion.getLastRow();  
	        int firstColumn = mergedRegion.getFirstColumn();  
	        int lastColumn 	= mergedRegion.getLastColumn();  
	        
	        //如果 cell 在 mergedRegion 中
	        if(firstRow <= rowIndex && rowIndex <= lastRow){
	        	if(firstColumn <= columnIndex && columnIndex <= lastColumn){
	                return mergedRegion ;  
	            }  
	        }*/
	    }
		
		return -1;
	}
	
	/**
	 * 通过 cell 获取 cell 所在的 "合并单元格"(即 region)
	 */
	public static CellRangeAddress getMergedRegion(XSSFCell cell) {
		
		XSSFSheet sheet = cell.getSheet();
		
		int index = getMergedRegionIndex(cell);
		
		if(index >= 0) {
			CellRangeAddress mergedRegion = sheet.getMergedRegion(index);
			
			//System.out.println("5555> ("+mergedRegion.getFirstColumn()+","+mergedRegion.getFirstRow()+")-("
//					+mergedRegion.getLastColumn()+","+mergedRegion.getLastRow()+")");
			
			return mergedRegion;
			
		}else {
			return null;
		}
		
	}
}
